/*
 * Copyright (c) 2001, 2002 Boris Pruessmann and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v0.5 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.perforce.api;

import net.sourceforge.perforce.api.internal.ClientApi;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * Activator for the perforce api plugin.
 * 
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net>Boris
 *         Pruessmann</a>
 */
public class PerforceApiPlugin extends Plugin {

  /** The unique identifier of the plugin. */
  public static final String ID = "net.sourceforge.perforce.api"; //$NON-NLS-1$

  /** Stores the singleton instance, returned by getPlugin(). */
  private static PerforceApiPlugin plugin;

  public PerforceApiPlugin() {
  }

  /**
   * Returns the sinlgeton instance of the plugin.
   * 
   * @return the singleton instance.
   */
  public static PerforceApiPlugin getPlugin() {
    return plugin;
  }

  /**
   * Creates a class implementing the IClientApi interface.
   * 
   * @return the IClientApi compatible instance.
   */
  public static IClientApi createClientApi() {
    return new ClientApi();
  }

  @Override
  public void start(BundleContext context) throws Exception {
    super.start(context);
    plugin = this;

    Policy.localize("net.sourceforge.perforce.api.messages"); //$NON-NLS-1$

    // On MacOS X, we have to split the jni library into two parts.
    // Unfortunately,
    // we have to place one library in a directory on the path, that's why have
    // to
    // make a copy here.
    if (Platform.getOS().equals(Platform.OS_MACOSX)) {
      try {
        InputStream is = find(new Path("$os$/libperforce.dylib")).openStream(); //$NON-NLS-1$
        FileOutputStream os = new FileOutputStream("libperforce.dylib"); //$NON-NLS-1$

        byte[] buffer = new byte[8192];
        int read = -1;
        while ((read = is.read(buffer)) != -1) {
          os.write(buffer, 0, read);
        }
        os.close();
        is.close();
      } catch (FileNotFoundException e) {
        Status status =
            new Status(Status.ERROR, ID, 0, Policy.bind("PerforceApiPlugin.startup"), e); //$NON-NLS-1$

        throw new CoreException(status);
      } catch (IOException e) {
        Status status =
            new Status(Status.ERROR, ID, 0, Policy.bind("PerforceApiPlugin.startup"), e); //$NON-NLS-1$

        throw new CoreException(status);
      }
    }

    try {
      System.loadLibrary("perforce"); //$NON-NLS-1$
    } catch (UnsatisfiedLinkError e) {
      logError("Can't load perforce native library", e);

      Status status = new Status(Status.ERROR, ID, 0, Policy.bind("PerforceApiPlugin.startup"), e); //$NON-NLS-1$
      throw new CoreException(status);
    }
  }

  @Override
  public void stop(BundleContext context) throws Exception {
    if (Platform.getOS().equals(Platform.OS_MACOSX)) {
      // Remove libperforce.dylib that we have to copy on MacOS X
      File file = new File("libperforce.dylib"); //$NON-NLS-1$
      if (file.exists()) {
        file.delete();
      }
    }
    plugin = null;
    super.stop(context);
  }

  /**
   * Call this method to log the given status.
   * 
   * @param status the status to log.
   */
  public static void log(IStatus status) {
    getPlugin().getLog().log(status);
  }

  /**
   * Call this method to log an error with the given message & throwable.
   * 
   * @param message the message.
   * @param throwable the exception.
   */
  public static void logError(String message, Throwable throwable) {
    getPlugin().getLog().log(
        new Status(IStatus.ERROR, PerforceApiPlugin.ID, IStatus.ERROR, message, throwable));
  }
}
